package com.usooft.metaTalent.core.teach.service.base;

import com.usooft.framework.core.query.Limit;
import com.usooft.framework.core.query.Page;
import com.usooft.metaTalent.core.teach.entity.Course;
import com.usooft.metaTalent.core.teach.mapper.CourseMapper;
import com.usooft.metaTalent.core.teach.query.CourseQuery;
import com.usooft.metaTalent.core.teach.service.CourseService;
import com.usooft.metaTalent.core.teach.wrapper.CourseWrapper;
import java.lang.Long;
import java.lang.Override;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.lang.NonNull;

public abstract class BaseCourseService implements CourseService {
    @Autowired
    private CourseMapper courseMapper;

    @Override
    public Course get(@NonNull Long id) {
        return find(id).orElseThrow();
    }

    @Override
    public Optional<Course> find(@NonNull Long id) {
        return Optional.ofNullable(courseMapper.get(id));
    }

    @Override
    public List<CourseWrapper> list(CourseQuery query) {
        return courseMapper.list(query);
    }

    @Override
    public Page<CourseWrapper> page(CourseQuery query) {
        int rows = courseMapper.count(query.getFilter());
        return new Page<>(rows, rows == 0 ? new ArrayList<>() : courseMapper.list(query));
    }

    protected Optional<Course> findOne(CourseQuery.Filter filter, CourseQuery.Sorts sorts) {
        List<CourseWrapper> wrappers = list(CourseQuery.builder()
                                .filter(filter)
                                .sorts(sorts)
                                .limit(Limit.rowCount(1))
                                .build());
        return wrappers.stream().findFirst().map(Function.identity());
    }

    protected Optional<Course> findOne(CourseQuery.Filter filter) {
        return findOne(filter, CourseQuery.Sorts.builder().build());
    }

    @Override
    public int count(CourseQuery.Filter filter) {
        return courseMapper.count(filter);
    }

    protected Course internalAdd(Long name) {
        Course course = new Course();
        course.setName(name);

        course.setCreatedDate(LocalDateTime.now());
        course.setVersion(0);
        course.setIsDelete(false);
        courseMapper.add(course);
        return course;
    }

    protected void internalUpdate(@NonNull Course course) {
        course.setLastModifiedDate(LocalDateTime.now());

        int rows = courseMapper.update(course);
        if (rows == 0) {
            throw new OptimisticLockingFailureException("更新失败。可能课程 (" + course.getId() + ") 的版本 (" + course.getVersion() + ") 已不是最新");
        }
        course.setVersion(course.getVersion() + 1);
    }
}
